package com.snpic.appaw.module.insure.util.s3;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;


/**
 * 图片添加水印工具类
 * 支持文字水印和图片水印
 * 利用jdk，不依赖第三方库
 */
public class ImageWatermarkUtils {
	private static final Logger log = LoggerFactory.getLogger(ImageWatermarkUtils.class);

	// 水印字体
	private static final Font FONT = new Font("Dialog", Font.PLAIN, 20);

	// 透明度
	private static final AlphaComposite COMPOSITE = AlphaComposite
		.getInstance(AlphaComposite.SRC_OVER, 0.6f);

	// 水印之间的间隔
	private static final int X_MOVE = 150;

	// 水印之间的间隔
	private static final int Y_MOVE = 200;

	public static Font getCustomFont(ResourceLoader resourceLoader) {
		Font customFont = null;
		try {
			Resource resource = resourceLoader.getResource("classpath:/font.ttf");
			InputStream inputStream = resource.getInputStream();
			customFont = Font.createFont(Font.TRUETYPE_FONT, inputStream);
		} catch (IOException | FontFormatException e) {
			e.printStackTrace();
		}
		return customFont;
	}

	/**
	 * 打水印(文字)  --循环 斜角
	 *
	 * @param srcImgPath       源文件地址
	 * @param font             字体
	 * @param markContentColor 水印颜色
	 * @param waterMarkContent 水印内容
	 * @param outImgPath       输出文件的地址
	 */
	public static void markWithContent(String srcImgPath, Font font, Color markContentColor, String waterMarkContent, String outImgPath) {
		FileOutputStream fos = null;
		try {
			// 读取原图片信息
			File srcFile = new File(srcImgPath);
			File outFile = new File(outImgPath);
			BufferedImage srcImg = ImageIO.read(srcFile);

			// 图片宽、高
			int imgWidth = srcImg.getWidth();
			int imgHeight = srcImg.getHeight();

			// 图片缓存
			BufferedImage bufImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);

			// 创建绘图工具
			Graphics2D graphics = bufImg.createGraphics();

			// 画入原始图像
			graphics.drawImage(srcImg, 0, 0, imgWidth, imgHeight, null);

			// 设置水印颜色
			graphics.setColor(markContentColor);

			// 设置水印透明度
			graphics.setComposite(COMPOSITE);

			// 设置倾斜角度
			graphics.rotate(Math.toRadians(-35), (double) bufImg.getWidth() / 2,
				(double) bufImg.getHeight() / 2);

			// 设置水印字体
			graphics.setFont(font);

			// 消除java.awt.Font字体的锯齿
			graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

			int xCoordinate = -imgWidth / 2, yCoordinate;
			// 字体长度
			int markWidth = FONT.getSize() * getTextLength(waterMarkContent);
			// 字体高度
			int markHeight = FONT.getSize();

			// 循环添加水印
			while (xCoordinate < imgWidth * 1.5) {
				yCoordinate = -imgHeight / 2;
				while (yCoordinate < imgHeight * 1.5) {
					graphics.drawString(waterMarkContent, xCoordinate, yCoordinate);
					yCoordinate += markHeight + Y_MOVE;
				}
				xCoordinate += markWidth + X_MOVE;
			}

			// 释放画图工具
			graphics.dispose();

			// 输出图片
			fos = new FileOutputStream(outFile);
			ImageIO.write(bufImg, "jpg", fos);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (fos != null) {
				try {
					fos.flush();
					fos.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}


	//计算水印文本长度
	//1、中文长度即文本长度 2、英文长度为文本长度二分之一
	public static int getTextLength(String text) {
		//水印文字长度
		int length = text.length();

		for (int i = 0; i < text.length(); i++) {
			String s = String.valueOf(text.charAt(i));
			if (s.getBytes().length > 1) {
				length++;
			}
		}
		length = length % 2 == 0 ? length / 2 : length / 2 + 1;
		return length;
	}

	/**
	 * 添加文字水印
	 *
	 * @param srcImgPath    源图片路径
	 * @param tarImgPath    目标图片路径
	 * @param watermarkText 水印文字
	 * @param font          水印字体
	 * @param color         水印颜色
	 * @param x             水印横坐标
	 * @param y             水印纵坐标
	 * @param alpha         水印透明度
	 */
	public static void addWatermarkByText(String srcImgPath, String tarImgPath, String watermarkText, Font font, Color color, int x, int y, float alpha) {
		try {
			int textLength = ImageWatermarkUtils.getTextLength(watermarkText);
			// 读取源图片
			BufferedImage srcImg = ImageIO.read(new File(srcImgPath));
			// 获取图片宽度和高度
			int srcImgWidth = srcImg.getWidth();
			int srcImgHeight = srcImg.getHeight();
			// 创建目标图片
			BufferedImage tarImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
			// 获取Graphics2D对象
			Graphics2D g2d = tarImg.createGraphics();
			// 在目标图片上绘制源图片
			g2d.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
			// 设置水印文字字体、颜色、透明度
			g2d.setFont(font);
			g2d.setColor(color);
			g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
			// 绘制水印文字
			g2d.drawString(watermarkText, srcImgWidth - x - textLength, srcImgHeight - y);
			// 释放资源
			g2d.dispose();
			// 输出目标图片
			ImageIO.write(tarImg, "jpg", new File(tarImgPath));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 添加图片水印
	 *
	 * @param srcImgPath       源图片路径
	 * @param tarImgPath       目标图片路径
	 * @param watermarkImgPath 水印图片路径
	 * @param x                水印横坐标
	 * @param y                水印纵坐标
	 * @param alpha            水印透明度
	 */
	public static void addWatermarkByImage(String srcImgPath, String tarImgPath, String watermarkImgPath, int x, int y, float alpha) {
		try {
			// 读取源图片和水印图片
			BufferedImage srcImg = ImageIO.read(new File(srcImgPath));
			BufferedImage watermarkImg = ImageIO.read(new File(watermarkImgPath));
			// 获取图片宽度和高度
			int srcImgWidth = srcImg.getWidth();
			int srcImgHeight = srcImg.getHeight();
			// 创建目标图片
			BufferedImage tarImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
			// 获取Graphics2D对象
			Graphics2D g2d = tarImg.createGraphics();
			// 在目标图片上绘制源图片
			g2d.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
			// 设置水印透明度
			g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
			// 在目标图片上绘制水印图片
			g2d.drawImage(watermarkImg, x, y, null);
			// 释放资源
			g2d.dispose();
			// 输出目标图片
			ImageIO.write(tarImg, "jpg", new File(tarImgPath));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	//Color.darkGray
	public static void main(String[] args) {
//        ImageWatermarkUtils.markWithContent("C:\\Users\\Administrator\\Desktop\\1\\微信图片_20230406140754.png",
//                FONT,
//                Color.red,
//                "仅限天安财险车险报价承保专用",
//                "C:\\Users\\Administrator\\Desktop\\1\\sea2_watermark111.jpg");
		InputStream inStream = null;
		HttpURLConnection conn = null;
//        String url = "https://testesale.95505.cn/yxx_checkcar_dev/wechat/image/YC202340683eefa91/idPhoto/idPhoto20230406102502.jpg";
		String url = "http://10.100.134.148:8001/ngs/fs/get?file=messagend/123.png";
		try {
			URL httpUrl = new URL(url);
			conn = (HttpURLConnection) httpUrl.openConnection();
			conn.setRequestMethod("GET");
			conn.setConnectTimeout(5 * 1000);
			if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
				inStream = conn.getInputStream();//通过输入流获取图片数据
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		InputStream inputStream = ImageWatermarkUtils.markWithContent(inStream, FONT, Color.red, "仅限天安财险车险报价承保专用");
		System.out.println(inputStream);

	}

	/**
	 * 将BufferedImage转换为InputStream。
	 *
	 * @param srcImg     要转换的BufferedImage
	 * @param formatName 图像的格式
	 * @return 转换后的InputStream
	 * @throws IOException 如果写入InputStream时出错
	 */
	public static InputStream bufferedImageToInputStream(BufferedImage srcImg, String formatName) throws IOException {
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		ImageIO.write(srcImg, formatName, os);
		return new ByteArrayInputStream(os.toByteArray());
	}

	/**
	 * 打水印(文字)  --循环 斜角
	 *
	 * @param inStream         源文件流
	 * @param font             字体
	 * @param markContentColor 水印颜色
	 * @param waterMarkContent 水印内容
	 * @return 返回 InputStream
	 */
	public static InputStream markWithContent(InputStream inStream, Font font, Color markContentColor, String waterMarkContent) {
		FileOutputStream fos = null;
		InputStream out_inStream = null;
		try {
			// 读取原图片信息
			BufferedImage srcImg = ImageIO.read(inStream);

			// 图片宽、高
			int imgWidth = srcImg.getWidth();
			int imgHeight = srcImg.getHeight();
			// 图片缓存
			BufferedImage bufImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);

			// 创建绘图工具
			Graphics2D graphics = bufImg.createGraphics();

			// 画入原始图像
			graphics.drawImage(srcImg, 0, 0, imgWidth, imgHeight, null);

			// 设置水印颜色
			graphics.setColor(markContentColor);

			// 设置水印透明度
			graphics.setComposite(COMPOSITE);

			// 设置倾斜角度
			graphics.rotate(Math.toRadians(-35), (double) bufImg.getWidth() / 2,
				(double) bufImg.getHeight() / 2);

			// 设置水印字体
			graphics.setFont(font);

			// 消除java.awt.Font字体的锯齿
			graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

			int xCoordinate = -imgWidth / 2, yCoordinate;
			// 字体长度
			int markWidth = FONT.getSize() * getTextLength(waterMarkContent);
			// 字体高度
			int markHeight = FONT.getSize();
			log.info("水印文字内容:" + waterMarkContent);
			// 循环添加水印
			while (xCoordinate < imgWidth * 1.5) {
				yCoordinate = -imgHeight / 2;
				while (yCoordinate < imgHeight * 1.5) {
					graphics.drawString(new String(waterMarkContent.getBytes("UTF-8"), "UTF-8"), xCoordinate, yCoordinate);
					yCoordinate += markHeight + Y_MOVE;
				}
				xCoordinate += markWidth + X_MOVE;
			}
			// 释放画图工具
			graphics.dispose();
			// 输出图片
			ByteArrayOutputStream os = new ByteArrayOutputStream();
			ImageIO.write(bufImg, "jpg", os);
			out_inStream = new ByteArrayInputStream(os.toByteArray());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (fos != null) {
				try {
					fos.flush();
					fos.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return out_inStream;
	}

	/**
	 * 计算字节流的长度
	 * @param input
	 * @return
	 * @throws IOException
	 */
	public static byte[] toByteArray(InputStream input) throws IOException {
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		byte[] buffer = new byte[4096];
		int n;
		while (-1 != (n = input.read(buffer))) {
			output.write(buffer, 0, n);
		}
		return output.toByteArray();
	}

}
